using Dapper;
using MediatR;
using Microsoft.Extensions.Logging;
using RBAC.Domain.ArrivalInspection;
using RBAC.ErrorCode;
using RBAC.Interstructrue.Base;
using RBAC.Write.Api.Application.Command.ArrivalInspection;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;

namespace RBAC.Write.Api.Application.Handler.ArrivalInspection
{
    /// <summary>
    /// 修改到货检验（全量覆盖明细与附件）
    /// </summary>
    public class UpdateArrivalInspectionHandler : IRequestHandler<UpdateArrivalInspectionCommand, APIResult<long>>
    {
        private readonly IBaseRepository<ArrivalInspectionInfo> _headerRepo;
        private readonly IDbConnectionFactory _connectionFactory;
        private readonly ILogger<UpdateArrivalInspectionHandler> _logger;

        public UpdateArrivalInspectionHandler(
            IBaseRepository<ArrivalInspectionInfo> headerRepo,
            IDbConnectionFactory connectionFactory,
            ILogger<UpdateArrivalInspectionHandler> logger)
        {
            _headerRepo = headerRepo;
            _connectionFactory = connectionFactory;
            _logger = logger;
        }

        public Task<APIResult<long>> Handle(UpdateArrivalInspectionCommand request, CancellationToken cancellationToken)
        {
            var res = new APIResult<long>();
            try
            {
                if (request == null || request.Id <= 0)
                {
                    res.Code = APIEnums.Fail;
                    res.Msg = "参数错误";
                    return Task.FromResult(res);
                }
                if (request.Items == null || request.Items.Count == 0)
                {
                    res.Code = APIEnums.Fail;
                    res.Msg = "明细不能为空";
                    return Task.FromResult(res);
                }

                // 校验存在且未删除
                var exists = _headerRepo.QueryFirstOrDefault<int>(
                    "SELECT COUNT(1) FROM ArrivalInspectionInfo WHERE Id = @Id AND IsDeleted = 0",
                    new { request.Id });
                if (exists == 0)
                {
                    res.Code = APIEnums.Fail;
                    res.Msg = "记录不存在或已删除";
                    return Task.FromResult(res);
                }

                // 解析日期
                if (!DateTime.TryParse(request.InspectionDate, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal, out var inspectionDate))
                {
                    if (!DateTime.TryParse(request.InspectionDate, out inspectionDate))
                    {
                        res.Code = APIEnums.Fail;
                        res.Msg = "检验日期格式不正确";
                        return Task.FromResult(res);
                    }
                }
                DateTime? purchaseDate = null;
                if (!string.IsNullOrWhiteSpace(request.PurchaseDate) && DateTime.TryParse(request.PurchaseDate, out var pd))
                {
                    purchaseDate = pd;
                }

                using (var conn = _connectionFactory.CreateConnectionWithRetry())
                using (var tran = conn.BeginTransaction())
                {
                    try
                    {
                        // 更新单头
                        var updateHeaderSql = @"UPDATE ArrivalInspectionInfo SET
Subject=@Subject,
InspectionDate=@InspectionDate,
Inspector=@Inspector,
Department=@Department,
Remark=@Remark,
PurchaseOrderNo=@PurchaseOrderNo,
SupplierId=@SupplierId,
SupplierName=@SupplierName,
PurchaseDate=@PurchaseDate,
PurchaseContact=@PurchaseContact,
ContactPhone=@ContactPhone,
Buyer=@Buyer,
PurchaseDept=@PurchaseDept,
ProjectName=@ProjectName
WHERE Id=@Id AND IsDeleted=0;";
                        conn.Execute(updateHeaderSql, new
                        {
                            Id = request.Id,
                            Subject = request.Subject?.Trim(),
                            InspectionDate = inspectionDate,
                            Inspector = request.Inspector ?? string.Empty,
                            Department = request.Department ?? string.Empty,
                            Remark = request.Remark ?? string.Empty,
                            PurchaseOrderNo = request.PurchaseOrderNo ?? string.Empty,
                            SupplierId = request.SupplierId ?? string.Empty,
                            SupplierName = request.SupplierName ?? string.Empty,
                            PurchaseDate = purchaseDate,
                            PurchaseContact = request.PurchaseContact ?? string.Empty,
                            ContactPhone = request.ContactPhone ?? string.Empty,
                            Buyer = request.Buyer ?? string.Empty,
                            PurchaseDept = request.PurchaseDept ?? string.Empty,
                            ProjectName = request.ProjectName ?? string.Empty
                        }, tran);

                        // 先删子表（物理）
                        conn.Execute("DELETE FROM ArrivalInspectionItem WHERE InspectionId=@InspectionId;", new { InspectionId = request.Id }, tran);
                        conn.Execute("DELETE FROM ArrivalInspectionAttachment WHERE InspectionId=@InspectionId;", new { InspectionId = request.Id }, tran);

                        // 重建明细
                        const string insertItemSql = @"INSERT INTO ArrivalInspectionItem 
(InspectionId, PurchaseOrderNo, MaterialCode, MaterialName, SpecModel, Unit, Brand, PurchaseQty, ReceivedQty, InspectionType, InspectQty, QualifiedQty, UnqualifiedQty, InspectResult, UnqualifiedReason, Remark)
VALUES
(@InspectionId, @PurchaseOrderNo, @MaterialCode, @MaterialName, @SpecModel, @Unit, @Brand, @PurchaseQty, @ReceivedQty, @InspectionType, @InspectQty, @QualifiedQty, @UnqualifiedQty, @InspectResult, @UnqualifiedReason, @Remark);";
                        foreach (var d in request.Items)
                        {
                            conn.Execute(insertItemSql, new
                            {
                                InspectionId = request.Id,
                                PurchaseOrderNo = d.PurchaseOrderNo ?? request.PurchaseOrderNo ?? string.Empty,
                                MaterialCode = d.MaterialCode ?? string.Empty,
                                MaterialName = d.MaterialName ?? string.Empty,
                                SpecModel = d.SpecModel ?? string.Empty,
                                Unit = d.Unit ?? string.Empty,
                                Brand = d.Brand ?? string.Empty,
                                PurchaseQty = d.PurchaseQty,
                                ReceivedQty = d.ReceivedQty,
                                InspectionType = d.InspectionType ?? string.Empty,
                                InspectQty = d.InspectQty,
                                QualifiedQty = d.QualifiedQty,
                                UnqualifiedQty = d.UnqualifiedQty,
                                InspectResult = d.InspectResult ?? string.Empty,
                                UnqualifiedReason = d.UnqualifiedReason ?? string.Empty,
                                Remark = d.Remark ?? string.Empty
                            }, tran);
                        }

                        // 重建附件
                        if (request.Attachments != null && request.Attachments.Count > 0)
                        {
                            const string insertAttSql = @"INSERT INTO ArrivalInspectionAttachment 
(InspectionId, FileName, FilePath, FileSize, UploadTime, Uploader, Remark)
VALUES
(@InspectionId, @FileName, @FilePath, @FileSize, @UploadTime, @Uploader, @Remark);";
                            foreach (var a in request.Attachments)
                            {
                                conn.Execute(insertAttSql, new
                                {
                                    InspectionId = request.Id,
                                    FileName = a.FileName,
                                    FilePath = a.FilePath,
                                    FileSize = a.FileSize,
                                    UploadTime = ParseOrNow(a.UploadTime),
                                    Uploader = a.Uploader ?? request.UpdateUser ?? string.Empty,
                                    Remark = a.Remark ?? string.Empty
                                }, tran);
                            }
                        }

                        tran.Commit();
                    }
                    catch
                    {
                        try { tran.Rollback(); } catch { }
                        throw;
                    }
                }

                res.Code = APIEnums.Success;
                res.Msg = "修改成功";
                res.Data = request.Id;
            }
            catch (Exception ex)
            {
                _logger?.LogError(ex, "修改到货检验失败: {Message}", ex.Message);
                res.Code = APIEnums.Error;
                res.Msg = "修改到货检验失败";
            }
            return Task.FromResult(res);
        }

        private static DateTime ParseOrNow(string? dt)
        {
            if (string.IsNullOrWhiteSpace(dt)) return DateTime.Now;
            if (DateTime.TryParse(dt, out var d)) return d;
            return DateTime.Now;
        }
    }
}
